package com.zbs.framework.common.utils;

import com.alibaba.fastjson.JSONArray;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.CaseFormat;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.util.ObjectUtils;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CommonUtil {

    public static final Pattern phonePattern = Pattern.compile("^(1)\\d{10}$");

    /**
     * 英文简写（默认）如：2010-12-01
     */
    public static String FORMAT_SHORT = "yyyy-MM-dd";
    /**
     * 英文简写（默认）如：2010-12-01
     */
    public static String FORMAT_DIY = "yyyy/MM/dd";

    /**
     * 英文全称  如：2010-12-01 23:15:06
     */
    public static String FORMAT_LONG = "yyyy-MM-dd HH:mm:ss";

    /**
     * 精确到毫秒的完整时间    如：yyyy-MM-dd HH:mm:ss.S
     */
    public static String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss.S";

    /**
     * 中文简写  如：2010年12月01日
     */
    public static String FORMAT_SHORT_CN = "yyyy年MM月dd";

    /**
     * 中文全称  如：2010年12月01日  23时15分06秒
     */
    public static String FORMAT_LONG_CN = "yyyy年MM月dd日  HH时mm分ss秒";

    /**
     * 精确到毫秒的完整中文时间
     */
    public static String FORMAT_FULL_CN = "yyyy年MM月dd日  HH时mm分ss秒SSS毫秒";

    /**
     * 获得默认的 date pattern
     */
    public static String getDatePattern() {
        return FORMAT_LONG;
    }
    /**
     * 获得默认的 date
     */
    public static String getDatePatt() {
        return FORMAT_DIY;
    }
    public static String getDateShot() {
        return FORMAT_SHORT;
    }


    public static boolean isZeroLengthTrimString(String value) {
        return value == null || value.trim().length() == 0;
    }

    public static boolean isNotZeroLengthTrimString(String value) {
        return !(isZeroLengthTrimString(value));
    }

    public static String getParamValue(HttpServletRequest request, String name) {
        String value = request.getParameter(name);
        if (isZeroLengthTrimString(value)) {
            return "";
        }
        return value;
    }

    public static Date getDateStart(String yyyyMMdd) {
        if (yyyyMMdd == null) return null;
        try {
            String[] calendar = yyyyMMdd.split("-");
            GregorianCalendar gc = new GregorianCalendar();
            gc.set(Integer.parseInt(calendar[0]), Integer.parseInt(calendar[1]) - 1, Integer.parseInt(calendar[2]), 0, 0,
                    0);
            return gc.getTime();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取当天的第几分钟
     * @param date
     * @return
     */
    public static int getMinutesInDay(Date date){
        return (int) (((date.getTime()/1000)%86400)/60);
    }

    public static Date getDateEnd(String yyyyMMdd) {
        if (yyyyMMdd == null) return null;
        try {
            String[] calendar = yyyyMMdd.split("-");
            GregorianCalendar gc = new GregorianCalendar();
            gc.set(Integer.parseInt(calendar[0]), Integer.parseInt(calendar[1]) - 1, Integer.parseInt(calendar[2]), 23, 59,
                    59);
            return gc.getTime();
        } catch (Exception e) {
            return null;
        }
    }

    public static <T> boolean contains(T[] arr, T target) {
        if (arr == null || arr.length == 0 || target == null) return false;
        for (T a : arr) {
            if (target.equals(a)) return true;
        }
        return false;
    }

    /**
     * 从src中剔除target
     *
     * @param src
     * @param target
     * @return
     */
    public static Long[] except(Long[] src, Long[] target) {
        if (src == null || src.length == 0 || target == null || target.length == 0)
            return src;
        List<Long> result = new ArrayList<>();
        for (int i = 0; i < src.length; i++) {
            if (contains(target, src[i])) continue;
            result.add(src[i]);
        }
        return result.toArray(new Long[result.size()]);
    }


    public static String getIdSQLParam(Long[] ids) {
        if (ids == null || ids.length == 0) {
            return null;
        }
        StringBuffer param = new StringBuffer("");
        for (int i = 0; i < ids.length; i++) {
            if (i > 0) {
                param.append(",");
            }
            param.append("?");
        }
        return param.toString();
    }

    public static String getCategoryOrderStr(List<String> ids) {
        if (ids == null || ids.size() == 0) {
            return "";
        }
        StringBuffer param = new StringBuffer("");
        for (int i = 0; i < ids.size(); i++) {
            if (i > 0) {
                param.append(",");
            }
            param.append(ids.get(i));
        }
        return param.toString();
    }

    public static String getIdSQLValue(Long[] ids) {
        if (ids == null || ids.length == 0) {
            return null;
        }
        StringBuffer param = new StringBuffer("");
        for (int i = 0; i < ids.length; i++) {
            if (i > 0) {
                param.append(",");
            }
            param.append(String.valueOf(ids[i]));
        }
        return param.toString();
    }

    public static String getArrSQLValue(Integer[] values) {
        if (values == null || values.length == 0) {
            return null;
        }
        StringBuffer param = new StringBuffer("");
        for (int i = 0; i < values.length; i++) {
            if (i > 0) {
                param.append(",");
            }
            param.append(String.valueOf(values[i]));
        }
        return param.toString();
    }

    public static String joinString(List<String> values, String separator) {
        if (values == null || values.size() == 0) {
            return null;
        }
        StringBuilder builder = new StringBuilder("");
        for (int i = 0; i < values.size(); i++) {
            if (i > 0) {
                builder.append(separator);
            }
            builder.append(values.get(i));
        }
        return builder.toString();
    }


    public static SimpleDateFormat getSampleDateFormat(String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf;
    }

    public static String getURL(String url, String menuId, String method) {
        return url + "?actionMethod=" + method + "&menuId=" + menuId;
    }

    /**
     * 密码加密的方法
     *
     * @param password
     * @return
     */
    public static String encrypt(String password) {
        String enStr = null;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update("meeno".getBytes());
            byte[] pswKey = md.digest();
            DESKeySpec desKeySpec = new DESKeySpec(pswKey);
            SecretKeyFactory desKeyFac = SecretKeyFactory.getInstance("DES");
            SecretKey desKey = desKeyFac.generateSecret(desKeySpec);
            Cipher encryptCipher = Cipher.getInstance("DES");
            encryptCipher.init(Cipher.ENCRYPT_MODE, desKey);
            byte[] enPassword = encryptCipher.doFinal(password.getBytes(StandardCharsets.UTF_8));
            enStr = new String(Base64.getEncoder().encode(enPassword), StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return enStr;
    }

    /**
     * 32位md5加密方法
     * @param sourceStr
     * @return
     */
    public static String MD5_32(String sourceStr) {
        String result = "";
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(sourceStr.getBytes(StandardCharsets.UTF_8));
            byte[] b = md.digest();
            int i;
            StringBuilder buf = new StringBuilder("");
            for (byte value : b) {
                i = value;
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            result = buf.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * java 
     * @param clazz
     * @param obj
     * @param fileName
     * @param value
     * @throws IllegalAccessException
     */
    public static void setValues(Class<?> clazz, Object obj, String fileName, Object value) throws IllegalAccessException {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.getName().equals(fileName)) {
                field.set(obj, value);
            }
        }
    }
    /**
     * 递归利用反射获取字段的值
     *
     * 调用示例请参考第二段单元测试代码
     *
     * @param fieldName 字段名称，支持多级，如：name person.student.className
     * @param data 需要从里面提前字段值的对象
     */
    public static Object getFieldValueByReflect(String fieldName, Object data) throws Exception {
        // fieldName 是否包含 ,
        boolean fieldNameContainsDot = fieldName.contains(".");
        int indexOfDotInFieldName = fieldName.indexOf(".");
        Object result = getFieldObject(fieldName,data);
        // 包含 , 并且 result 不为 null 需要继续递归
        if (fieldNameContainsDot && result != null) {
            return getFieldValueByReflect(fieldName.substring(indexOfDotInFieldName + 1), result);
        } else {
            return result;
        }
    }




    /**
     * 递归利用反射获取字段的值
     *
     * 调用示例请参考第二段单元测试代码
     *
     * @param fieldName 字段名称，支持多级，如：name person.student.className
     * @param data 需要从里面提前字段值的对象
     */
    public static <T> T getFieldValueByReflect(String fieldName, Object data,Class<T> clazz) throws Exception {
        // fieldName 是否包含 ,
        boolean fieldNameContainsDot = fieldName.contains(".");
        int indexOfDotInFieldName = fieldName.indexOf(".");
        Object result = getFieldObject(fieldName,data);

        // 包含 , 并且 result 不为 null 需要继续递归
        if (fieldNameContainsDot && result != null) {
            return getFieldValueByReflect(fieldName.substring(indexOfDotInFieldName + 1), result,clazz);
        } else {
            return new ObjectMapper().convertValue(result,clazz);
        }
    }

    private static Object  getFieldObject(String fieldName, Object data) throws Exception {
        // fieldName 是否包含 ,
        boolean fieldNameContainsDot = fieldName.contains(".");
        int indexOfDotInFieldName = fieldName.indexOf(".");
        // temp field name 会根据 fieldName 是否包含 , 而不同
        String tmpFieldName = fieldName;
        if (fieldNameContainsDot) {
            tmpFieldName = fieldName.substring(0, indexOfDotInFieldName);
        }

        // 通过字符串拼接的方式，拼接出实体类相对应的get方法;
        String methodName = "get" + tmpFieldName.substring(0, 1).toUpperCase() + tmpFieldName.substring(1);
        // 通过反射拿到类对象，再获取类对象的 methodName 这个方法
        Method declaredMethod = data.getClass().getDeclaredMethod(methodName, (Class<?>[]) null);
        // 通过invoke提交对象，执行declaredMethod这个方法
        return declaredMethod.invoke(data);
    }

    /**
     * 生成随机数字字符串
     *
     * @param length
     * @return
     */
    public static String getRandomNumString(int length) { // length表示生成字符串的长度
        String base = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 判断字符串是否匹配正则表达式.
     *
     * @param aimStr 目标字符串
     * @param regex  正则表达式
     * @return 匹配结果(true:匹配, false:不匹配)
     **/
    public static boolean getMatchResult(final String aimStr, final String regex) {
        try {
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(aimStr);
            return matcher.matches();
        } catch (Exception e) {
            // TODO: handle exception
            return false;
        }
    }

    /**
     * 判断字符串是否匹配手机号.
     *
     * @param aimStr 目标字符串
     * @return 匹配结果(true:匹配, false:不匹配)
     **/
    public static boolean matchPhone(String aimStr) {
        try {
            Matcher matcher = phonePattern.matcher(aimStr);
            return matcher.matches();
        } catch (Exception e) {
            // TODO: handle exception
            return false;
        }
    }


    /**
     * 将json数组转化为Long型
     *
     * @param jsonArray
     * @return
     */
    public static Long[] getJsonToLongArray(JSONArray jsonArray) {
        try {
            Long[] arr = new Long[jsonArray.size()];
            for (int i = 0; i < jsonArray.size(); i++) {
                arr[i] = jsonArray.getLong(i);
            }
            return arr;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 将json数组转化为Integer型
     *
     * @param jsonArray
     * @return
     */
    public static Integer[] getJsonToIntegerArray(JSONArray jsonArray) {
        try {
            Integer[] arr = new Integer[jsonArray.size()];
            for (int i = 0; i < jsonArray.size(); i++) {
                arr[i] = jsonArray.getInteger(i);
            }
            return arr;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 将json数组转化为String型
     *
     * @param jsonArray
     * @return
     */
    public static String[] getJsonToStringArray(JSONArray jsonArray) {
        try {
            String[] arr = new String[jsonArray.size()];
            for (int i = 0; i < jsonArray.size(); i++) {
                arr[i] = jsonArray.getString(i);
            }
            return arr;
        } catch (Exception e) {
            return null;
        }
    }


    public static <T> List<T> getLimitList(List<T> list, Integer pageIndex, Integer pageSize) {
        if ((list == null) || (list.size() == 0)) {
            return list;
        }
        if ((pageIndex != null) && (pageSize != null)) {
            //需要分页
            if ((pageIndex - 1) * pageSize > (list.size() - 1)) {
                //起始位置已越界
                return list;
            } else {
                int startIndex = (pageIndex - 1) * pageSize;
                int endIndex = Math.min(pageIndex * pageSize, list.size());
                return list.subList(startIndex, endIndex);
            }
        }
        return list;
    }

    /**
     * 获取发起请求的客户端地址
     *
     * @param request
     * @return
     */
    public static String getRemoteHost(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }

    /**
     * 获取客户端访问的真实ip地址
     *
     * @param request
     * @return
     */
    public static String getIpAddress(HttpServletRequest request) {
        String client_ip = request.getHeader("x-forwarded-for");
        if (client_ip == null || client_ip.length() == 0 || "unknown".equalsIgnoreCase(client_ip)) {
            client_ip = request.getHeader("Proxy-Client-IP");
        }
        if (client_ip == null || client_ip.length() == 0 || "unknown".equalsIgnoreCase(client_ip)) {
            client_ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (client_ip == null || client_ip.length() == 0 || "unknown".equalsIgnoreCase(client_ip)) {
            client_ip = request.getRemoteAddr();
            if (client_ip.equals("127.0.0.1") || client_ip.equals("0:0:0:0:0:0:0:1")) {
                //根据网卡取本机配置的IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                client_ip = inet.getHostAddress();
            }
        }
        //对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (client_ip != null && client_ip.length() > 15) { //"***.***.***.***".length() = 15
            if (client_ip.indexOf(",") > 0) {
                client_ip = client_ip.substring(0, client_ip.indexOf(","));
            }
        }

        return client_ip;
    }

    /**
     * 获取匿名name
     *
     * @param name
     * @return
     */
    public static String getAnonymousName(String name) {
        try {
            if (CommonUtil.isZeroLengthTrimString(name)) return "";
            String x = "***";
            if (name.length() == 1) {
                return name + x;
            }
            StringBuffer an = new StringBuffer();
            an.append(name.charAt(0))
                    .append(x)
                    .append(name.charAt(name.length() - 1));
            return an.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param startDate
     * @param endDate
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date startDate, Date endDate) {
        Long between_days = -1L;
        try {
            Calendar calendar = new GregorianCalendar();
            int zoneOffset = calendar.get(Calendar.ZONE_OFFSET);
            Long days1 = (startDate.getTime() + zoneOffset) / (1000 * 3600 * 24);
            Long days2 = (endDate.getTime() + zoneOffset) / (1000 * 3600 * 24);
            between_days = days2 - days1;
        } catch (Exception e) {
            between_days = -1L;
        }
        return between_days.intValue();
    }

    public static int getDayOfWeek(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (calendar.getFirstDayOfWeek() != Calendar.SUNDAY)
            return calendar.get(Calendar.DAY_OF_WEEK);

        // 以周日为第一天
         int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
         return dayOfWeek == 1 ? 7 : dayOfWeek - 1;//
    }

    public static String getLongArrSQL(Long[] values) {
        if (values == null || values.length == 0) {
            return null;
        }
        StringBuffer param = new StringBuffer("");
        for (int i = 0; i < values.length; i++) {
            if (i > 0) {
                param.append(",");
            }
            param.append(values[i]);
        }
        return param.toString();
    }

    public static String getLongArrSQL(List<Long> values) {
        if (values == null || values.size() == 0) {
            return null;
        }
        StringBuffer param = new StringBuffer("");
        for (int i = 0; i < values.size(); i++) {
            if (i > 0) {
                param.append(",");
            }
            param.append(values.get(i));
        }
        return param.toString();
    }

    public static String getIntegerArrSQL(List<Integer> values) {
        if (values == null || values.size() == 0) {
            return null;
        }
        StringBuffer param = new StringBuffer("");
        for (int i = 0; i < values.size(); i++) {
            if (i > 0) {
                param.append(",");
            }
            param.append(values.get(i));
        }
        return param.toString();
    }

    public static Long[] getBigIntegerToLongValue(List<BigInteger> list) {
        Long[] l = new Long[list.size()];
        for (int i = 0; i < list.size(); i++) {
            l[i] = list.get(i).longValue();
        }
        return l;
    }

    /**
     * 去掉bean中所有属性为字符串的前后空格
     *
     * @param bean
     * @throws Exception
     */
    public static void trimStringAttr(Object... bean) {
        if (bean == null) return;
        //
        Field[] fields = bean.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field f = fields[i];
            if (f.getType().getName().equals("java.lang.String")) {
                try {
                    String key = f.getName();//获取字段名
                    Object value = getFieldValue(bean, key);
                    if (value == null)
                        continue;
                    setStringFieldValue(bean, key, value.toString().trim());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 利用反射通过get方法获取bean中字段fieldName的值
     *
     * @param bean
     * @param fieldName
     * @return
     * @throws Exception
     */
    private static Object getFieldValue(Object bean, String fieldName)
            throws Exception {
        StringBuffer sb = new StringBuffer();
        String methodName = sb.append("get")
                .append(fieldName.substring(0, 1).toUpperCase())
                .append(fieldName.substring(1)).toString();

        Object rObject = null;
        Method method = null;

        @SuppressWarnings("rawtypes")
        Class[] classArr = new Class[0];
        method = bean.getClass().getMethod(methodName, classArr);
        rObject = method.invoke(bean, new Object[0]);

        return rObject;
    }

    /**
     * 利用发射调用bean.set方法将value设置到字段
     *
     * @param bean
     * @param fieldName
     * @param value
     * @throws Exception
     */
    private static void setStringFieldValue(Object bean, String fieldName, String value)
            throws Exception {
        StringBuffer sb = new StringBuffer();
        String methodName = sb.append("set")
                .append(fieldName.substring(0, 1).toUpperCase())
                .append(fieldName.substring(1)).toString();

        /**
         * 利用发射调用bean.set方法将value设置到字段
         */
        Method method = bean.getClass().getMethod(methodName, String.class);
        method.invoke(bean, value);
    }

    /**
     * 根据预设格式返回当前日期
     * @return
     */
    public static String getNow() {
        return format(new Date());
    }

    public static Date getDate(){
        return new Date();
    }

    public static Date getDate(String format){
        return parse(getNow(format),format);
    }
    /**
     * 根据用户格式返回当前日期
     * @param format
     * @return
     */
    public static String getNow(String format) {
        return format(new Date(), format);
    }


    /**
     * 使用预设格式格式化日期
     * @param date
     * @return
     */
    public static String format(Date date) {
        return format(date, getDatePattern());
    }
    /**
     * 使用预设格式格式化日期
     * @param date
     * @return
     */
    public static String format1(Date date) {
        return format(date, getDatePatt());
    }

    public static String format2(Date date) {
        return format(date, getDateShot());
    }
    /**
     * 使用用户格式格式化日期
     * @param date 日期
     * @param pattern 日期格式
     * @return
     */
    public static String format(Date date, String pattern) {
        String returnValue = "";
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            returnValue = df.format(date);
        }
        return (returnValue);
    }

    /**
     * 使用预设格式提取字符串日期
     * @param strDate 日期字符串
     * @return
     */
    public static Date parse(String strDate) {
        return parse(strDate, getDatePattern());
    }

    public static Date parseShot(String strDate) {
        return parse(strDate, getDateShot());
    }

    /**
     * 使用用户格式提取字符串日期
     * @param strDate 日期字符串
     * @param pattern 日期格式
     * @return
     */
    public static Date parse(String strDate, String pattern) {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        try {
            return df.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 在日期上增加数个整月
     * @param date 日期
     * @param n 要增加的月数
     * @return
     */
    public static Date addMonth(Date date, int n) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, n);
        return cal.getTime();
    }

    /**
     * 在日期上增加天数
     * @param date 日期
     * @param n 要增加的天数
     * @return
     */
    public static Date addDay(Date date, int n) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, n);
        return cal.getTime();
    }

    /**
     * 在日期上增加天数
     * @param dateStr 日期
     * @param n 要增加的天数
     * @return
     */
    public static String addDay(String dateStr, int n) {
        Date date = parse(dateStr);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, n);
        return format(cal.getTime());
    }

    /**
     * 获取时间戳
     */
    public static String getTimeString() {
        SimpleDateFormat df = new SimpleDateFormat(FORMAT_FULL);
        Calendar calendar = Calendar.getInstance();
        return df.format(calendar.getTime());
    }

    /**
     * 获取日期年份
     * @param date 日期
     * @return
     */
    public static String getYear(Date date) {
        return format(date).substring(0, 4);
    }

    /**
     * 按默认格式的字符串距离今天的天数
     * @param date 日期字符串
     * @return
     */
    public static int countDays (String date) {
        long t = Calendar.getInstance().getTime().getTime();
        Calendar c = Calendar.getInstance();
        c.setTime(parse(date));
        long t1 = c.getTime().getTime();
        return (int)(t/1000 - t1/1000)/3600/24;
    }

//    /**
//     * 按用户格式字符串距离今天的天数
//     * @param date 日期字符串
//     * @param format 日期格式
//     * @return
//     */
//    public static int countDays (String date, String format) {
//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(Objects.requireNonNull(parse(getNow(), FORMAT_SHORT)));
//        long t = calendar.getTime().getTime();
//
//        Calendar c = Calendar.getInstance();
//        c.setTime(Objects.requireNonNull(parse(date, format)));
//        long t1 = c.getTime().getTime();
//        return (int)(t/1000 - t1/1000)/3600/24;
//    }

    /**
     *
     * @Title: getBackTime
     * @Description:
     * @param @param timestr
     * @param @return    设定文件
     * @return Date    返回类型
     * @throws
     */
    public static Date getBackTime(String timestr) {
        Date curTime = new Date();
        Date startTime = DateUtils.addMonth(curTime, -12);
        if (timestr.equals("ONEYEAE")) {
        } else if (timestr.equals("TWOYEAR")) {
            startTime = DateUtils.addMonth(curTime, -12 * 2);
        } else if (timestr.equals("ALL")) {
            startTime = null;
        }
        return startTime;
    }

    /**
     * 获取当前日期是星期几<br>
     *
     * @param date
     * @return 当前日期是星期几
     */
    public Integer getWeekOfDate(Date date) {
        Integer[] weekDays = { 7, 1, 2, 3, 4, 5, 6 };
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    /**
     * 计算时间差
     * @param startDate
     * @param endDate
     * @return
     */
    public static int countDays(Date startDate, Date endDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        long t = calendar.getTime().getTime();

        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        long t1 = c.getTime().getTime();
        return (int)(t/1000 - t1/1000)/3600/24;
    }

    public static int countDays(String startDateStr, String endDateStr) {
        Date startDate = parse(startDateStr);
        Date endDate = parse(endDateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        long t = calendar.getTime().getTime();

        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        long t1 = c.getTime().getTime();
        return (int)(t/1000 - t1/1000)/3600/24;
    }

    /**
     * 获取年月日的时间
     * @param date
     * @return
     */
    public static Date getDateEnd(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 时
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        // 分
        calendar.set(Calendar.MINUTE, 59);
        // 秒
        calendar.set(Calendar.SECOND, 59);
        // 毫秒
        calendar.set(Calendar.MILLISECOND, 0);

        return calendar.getTime();
    }

    public static Date getDateStart(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 时
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        // 分
        calendar.set(Calendar.MINUTE, 0);
        // 秒
        calendar.set(Calendar.SECOND, 0);
        // 毫秒
        calendar.set(Calendar.MILLISECOND, 0);

        return calendar.getTime();
    }

    /*
     * 0 指前面补充零
     * formatLength 字符总长度为 formatLength
     * d 代表为正数。
     */
    public static String frontCompWithZero(Long sourceDate,int formatLength) {
        return String.format("%0"+formatLength+"d", sourceDate);
    }

    /**
     * 在字符串后面追加 0，示例：str 为 1, length 为 4, 则为 "1000"
     *
     * @param str 被处理的字符串
     * @param length 处理之后的位数
     * @return
     */
    public static String numberAfterFillZero(String str, int length) {
        StringBuilder buffer = new StringBuilder(str);
        if (buffer.length() >= length) {
            return buffer.toString();
        } else {
            while (buffer.length() < length) {
                buffer.append("0");
            }
        }
        return buffer.toString();
    }



    /**
     * 获取本月第一天
     * @return
     */
    public static Date getMonthMinDate(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * 获取本月最后一天
     * @return
     */
    public static Date getMonthMaxDate(){
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(new Date());
        calendar2.set(Calendar.DAY_OF_MONTH, calendar2.getActualMaximum(Calendar.DAY_OF_MONTH));
        return getDateEnd(calendar2.getTime());
    }

    /**
     * 驼峰式的实体类属性名转换为数据表字段名
     * @param camelCaseStr  驼峰式的实体类属性名
     * @return  转换后的以"_"分隔的数据表字段名
     */
    public static String decamelize(String camelCaseStr){
        return ObjectUtils.isEmpty(camelCaseStr) ? "" : CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, camelCaseStr);
    }

    /**
     * 将下划线转为驼峰命名（class开头大写）
     * @param decamelize
     * @return
     */
    public static String camelCaseNameByClassName(String decamelize){
        return ObjectUtils.isEmpty(decamelize) ? "" : CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, decamelize);
    }

    /**
     * 将下划线转为驼峰命名（实体开头小写）
     * @param decamelize
     * @return
     */
    public static String camelCaseNameByPropertyName(String decamelize){
        return ObjectUtils.isEmpty(decamelize) ? "" : CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, decamelize);
    }




    /**
     * 字符串是否为空
     * @param cs   待检查的字符串
     * @return  空：true; 非空：false
     */
    public static boolean isBlank(final CharSequence cs) {
        int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (!Character.isWhitespace(cs.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    public static Map<String,Object> checkParams(Map<String,Object> oldParams){
        Map<String,Object> params = new HashMap<>();
        oldParams.keySet().forEach(key -> {
            if (!ObjectUtils.isEmpty(oldParams.get(key))){
                params.put(key,oldParams.get(key));
            }
        });
        return params;
    }

    /**
     * 将对象装换为map
     *
     * @param bean
     * @return
     */
    public static <T> Map<String, Object> beanToMap(T bean) {
        Map<String, Object> map = Maps.newHashMap();
        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            for (Object key : beanMap.keySet()) {
                if (beanMap.get(key) != null) {
                    map.put(key + "", beanMap.get(key));
                }
            }
        }
        return map;
    }

    /**
     * 将对象装换为map
     *
     * @param bean
     * @return
     */
    public static <T> Map<String, String> beanToMapStr(T bean) {
        Map<String, String> map = Maps.newHashMap();
        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            for (Object key : beanMap.keySet()) {
                map.put(key + "", beanMap.get(key).toString());
            }
        }
        return map;
    }

    /**
     * 将map装换为javabean对象
     *
     * @param map
     * @param bean
     * @return
     */
    public static <T> T mapToBean(Map<String, Object> map, T bean) {
        BeanMap beanMap = BeanMap.create(bean);
        beanMap.putAll(map);
        return bean;
    }

    /**
     * 将List<T>转换为List<Map<String, Object>>
     *
     * @param objList
     * @return
     */
    public static <T> List<Map<String, Object>> objectsToMaps(List<T> objList) {
        List<Map<String, Object>> list = Lists.newArrayList();
        if (objList != null && objList.size() > 0) {
            Map<String, Object> map = null;
            T bean = null;
            for (int i = 0, size = objList.size(); i < size; i++) {
                bean = objList.get(i);
                map = beanToMap(bean);
                list.add(map);
            }
        }
        return list;
    }
}